#include "TO_AST.h"
#include "ASTnode.h"
#include <cstdlib>

Program* get_Program(const parse* root);
void get_Id_List(const parse* now, vector<Node>& V);
Program_Body* get_Program_Body(const parse* now);
void get_Const_Declaration(const parse* now, vector<Const_Declaration*>& V);
Const_Variable* get_Const_Variable(const parse* now);
void get_Type_Declaration(const parse* now, vector<Type_Declaration*>& V);
Type* get_Ptype(const parse* now);
void get_Periods(const parse* now, vector<pair<Const_Variable*, Const_Variable*>>& V);
void get_Var_Declaration(const parse* now, vector<Var_Declaration*>& V);
void get_Subprogram_Declaration(const parse* now, vector<Subprogram_Declaration*>& V);
void get_Formal_Parameter(const parse* now, vector<Formal_Parameter*>& V);
Compound_Statement* get_Compound_Statement(const parse* now);
void get_Statement_List(const parse* now, vector<Statement*> &V);
Statement* get_Statement(const parse* now);
Assign_Statement* get_Assign_Statement(const parse* variable, const parse* expression);
Variable* get_Variable(const parse* now);
void get_Id_Varparts(const parse* now, int& type, vector<vector<Expression*>>& V1, vector<string>& V2, vector<int>& V3);
Procedure_Statement* get_Procedure_Statement(const parse* now);
IF_Statement* get_IF_Statement(const parse* expression, const parse* then_statement, const parse* else_part);
CASE_Statement* get_CASE_Statement(const parse* expression, const parse* case_body);
void get_Branch(const parse* now, vector<Branch*>& V);
void get_Const_List(const parse* now, vector<Const_Variable*>& V);
WHILE_Statement* get_WHILE_Statement(const parse* expression, const parse* statement);
REPEAT_Statement* get_REPEAT_Statement(const parse* statement_list, const parse* expression);
FOR_Statement* get_FOR_Statement(const parse* ID, const parse* expression1 , const parse* updown, const parse* expression2, const parse* statement);
void get_Expression_List(const parse* now, vector<Expression*>& V);
Expression* get_Expression(const parse* now);
Simple_Expression* get_Simple_Expression(const parse* now);
Term* get_Term(const parse* now);
Factor* get_Factor(const parse* now);
Unsigned_Const_Variable* get_Unsigned_Const_Variable(const parse* now);

//PPROGRAM: program_head SEMICOLON program_body DOT
//program_head: PROGRAM ID LPAR identifier_list RPAR
Program* get_Program(const parse* root)
{
    Program* program = new Program();
    program->ID = {root->children[0]->children[1]->value, root->children[0]->children[1]->line};
    get_Id_List(root->children[0]->children[3], program->para_list);
    program->program_body = get_Program_Body(root->children[2]);
    return program;
}
//identifier_list: identifier_list COMMA ID | ID
void get_Id_List(const parse* now, vector<Node>& V)
{
    if(now->children.size() == 1){
        V.push_back({now->children[0]->value, now->children[0]->line});
    }
    else if(now->children.size() == 3){
        get_Id_List(now->children[0], V);
        V.push_back({now->children[2]->value, now->children[2]->line});
    }
}
//program_body: const_declarations type_declarations var_declarations subprogram_declarations compound_statement
//const_declarations: CONST const_declaration SEMICOLON | 
//type_declarations: TYPE type_declaration SEMICOLON |
//var_declarations: VAR var_declaration SEMICOLON |
//subprogram_declarations: subprogram_declarations subprogram_declaration SEMICOLON |
Program_Body* get_Program_Body(const parse* now)
{
    Program_Body* program_body = new Program_Body();
    if(now->children[0]->children.size() == 3){
        get_Const_Declaration(now->children[0]->children[1],program_body->const_declaration);
    }
    if(now->children[1]->children.size() == 3){
        get_Type_Declaration(now->children[1]->children[1],program_body->type_declaration);
    }
    if(now->children[2]->children.size() == 3){
        get_Var_Declaration(now->children[2]->children[1],program_body->var_declaration);
    }
    if(now->children[3]->children.size() == 3){
        get_Subprogram_Declaration(now->children[3],program_body->subprogram_declaration);
    }
    program_body->compound_statement = get_Compound_Statement(now->children[4]);
    return program_body;
}
//const_declaration: const_declaration SEMICOLON ID EQUAL const_variable | ID EQUAL const_variable
void get_Const_Declaration(const parse* now, vector<Const_Declaration*>& V)
{
    if(now->children.size() == 5){
        get_Const_Declaration(now->children[0], V);
        Const_Declaration* const_declaration = new Const_Declaration();
        const_declaration->ID = {now->children[2]->value, now->children[2]->line};
        const_declaration->const_variable = get_Const_Variable(now->children[4]);
        V.push_back(const_declaration);
    }
    else if(now->children.size() == 3){
        Const_Declaration* const_declaration = new Const_Declaration();
        const_declaration->ID = {now->children[0]->value, now->children[0]->line};
        const_declaration->const_variable = get_Const_Variable(now->children[2]);
        V.push_back(const_declaration);
    }
}
//const_variable: ADD ID | SUB ID | ID | ADD NUM | SUB NUM | NUM | SSCH | MMCH
Const_Variable* get_Const_Variable(const parse* now)
{
    Const_Variable* const_variable = new Const_Variable();
    if(now->children.size() == 2){
        if(now->children[0]->token == "SUB"){
            const_variable->is_minus = true;
        }
        if(now->children[1]->token == "ID"){
            const_variable->id = now->children[1]->value;
            const_variable->var_value = {now->children[1]->value, now->children[1]->line};
            const_variable->mold = "id";
        }
        else if(now->children[1]->token == "INT"){
            const_variable->var_value = {now->children[1]->value, now->children[1]->line};
            const_variable->int_value = atoi(now->children[1]->value.c_str());
            const_variable->mold = "int";
        }
        else if(now->children[1]->token == "FLOAT"){
            const_variable->var_value = {now->children[1]->value, now->children[1]->line};
            const_variable->float_value = atof(now->children[1]->value.c_str());
            const_variable->mold = "float";            
        }
    }
    else if(now->children.size() == 1){
        if(now->children[0]->token == "ID"){
            const_variable->id = now->children[0]->value;
            const_variable->var_value = {now->children[0]->value, now->children[0]->line};
            const_variable->mold = "id";
        }
        else if(now->children[0]->token == "INT"){
            const_variable->var_value = {now->children[0]->value, now->children[0]->line};
            const_variable->int_value = atoi(now->children[0]->value.c_str());
            const_variable->mold = "int";
        }
        else if(now->children[0]->token == "FLOAT"){
            const_variable->var_value = {now->children[0]->value, now->children[0]->line};
            const_variable->float_value = atof(now->children[0]->value.c_str());
            const_variable->mold = "float";            
        }
        else if(now->children[0]->token == "SSCH"){
            const_variable->var_value = {now->children[0]->value, now->children[0]->line};
            const_variable->c = now->children[0]->value[0];
            const_variable->mold = "char";            
        }
        else if(now->children[0]->token == "MMCH"){
            const_variable->var_value = {now->children[0]->value, now->children[0]->line};
            const_variable->str = now->children[0]->value;
            const_variable->mold = "string";            
        }
    }
    return const_variable;
}
//type_declaration: type_declaration SEMICOLON ID EQUAL PTYPE | ID EQUAL PTYPE
void get_Type_Declaration(const parse* now, vector<Type_Declaration*>& V)
{
    if(now->children.size() == 5){
        get_Type_Declaration(now->children[0], V);
        Type_Declaration* type_declaration = new Type_Declaration();
        type_declaration->ID = {now->children[2]->value, now->children[2]->line};
        type_declaration->type = get_Ptype(now->children[4]); 
    }
    else if(now->children.size() == 3){
        Type_Declaration* type_declaration = new Type_Declaration();
        type_declaration->ID = {now->children[0]->value, now->children[0]->line};
        type_declaration->type = get_Ptype(now->children[2]);
    }
}
//PTYPE: standard_type | RECORD record_body END | ARRAY LBAR periods RBAR OF PTYPE
//standard_type: INTEGER | REAL | BOOLEAN | CHAR | STRING
//record_body: var_declaration | 
Type* get_Ptype(const parse* now)
{
    if(now->children.size() == 1){
        Type* type = new Type();
        type->mold = "standard";
        type->standard = {now->children[0]->children[0]->value, now->children[0]->children[0]->line};
        return type;
    }
    else if(now->children.size() == 3){
        Type* type = new Type();
        type->mold = "record";
        if(now->children[1]->children.size() == 1){
            get_Var_Declaration(now->children[1]->children[0], type->var_declaration);
        }
        return type;
    }
    else if(now->children.size() == 6){
        Type* type = new Type();
        type->mold = "array";
        get_Periods(now->children[2], type->array_range);
        parse* res = now->children[5];
        while(res->children.size() == 6){
            get_Periods(res->children[2], type->array_range);
            res = res->children[5];
        }
        if(res->children.size() == 1){
            type->array_type = "standard";
            type->standard = {res->children[0]->children[0]->value, res->children[0]->children[0]->line};
        }
        else if(res->children.size() == 3){
            type->array_type = "record";
            if(res->children[1]->children.size() == 1){
                get_Var_Declaration(res->children[1]->children[0], type->var_declaration);
            }           
        }
        return type;
    }
    else{
        return nullptr;
    }
}
//periods: periods COMMA period | period
//period: const_variable DDOT const_variable 
void get_Periods(const parse* now, vector<pair<Const_Variable*, Const_Variable*>>& V)
{
    if(now->children.size() == 3){
        get_Periods(now->children[0], V);
        Const_Variable* left = get_Const_Variable(now->children[2]->children[0]);
        Const_Variable* right = get_Const_Variable(now->children[2]->children[2]);
        V.push_back(make_pair(left, right));
    }
    else if(now->children.size() == 1){
        Const_Variable* left = get_Const_Variable(now->children[0]->children[0]);
        Const_Variable* right = get_Const_Variable(now->children[0]->children[2]);
        V.push_back(make_pair(left, right));
    }
}
//var_declaration: var_declaration SEMICOLON identifier_list COLON PTYPE | identifier_list COLON PTYPE
void get_Var_Declaration(const parse* now, vector<Var_Declaration*>& V)
{
    if(now->children.size() == 5){
        get_Var_Declaration(now->children[0], V);
        Var_Declaration* var_declaration = new Var_Declaration();
        get_Id_List(now->children[2], var_declaration->ID);
        var_declaration->type = get_Ptype(now->children[4]);
        V.push_back(var_declaration);
    }
    else if(now->children.size() == 3){
        Var_Declaration* var_declaration = new Var_Declaration();
        get_Id_List(now->children[0], var_declaration->ID);
        var_declaration->type = get_Ptype(now->children[2]);
        V.push_back(var_declaration);
    }
}
//subprogram_declarations: subprogram_declarations subprogram_declaration SEMICOLON |
//subprogram_declaration: subprogram_head SEMICOLON program_body
//subprogram_head: FUNCTION ID formal_parameter COLON standard_type | PROCEDURE ID formal_parameter
//formal_parameter: LPAR parameter_lists RPAR | 
void get_Subprogram_Declaration(const parse* now, vector<Subprogram_Declaration*>& V)
{
    if(now->children.size() == 3){
        get_Subprogram_Declaration(now->children[0], V);
        Subprogram_Declaration* subprogram_declaration = new Subprogram_Declaration();
        parse* res = now->children[1];
        parse* head = res->children[0];
        if(head->children.size() == 5){
            subprogram_declaration->mold = "function";
            subprogram_declaration->ID = {head->children[1]->value, head->children[1]->line};
            subprogram_declaration->return_type = {head->children[4]->children[0]->value, head->children[4]->children[0]->line};  
            if(head->children[2]->children.size() == 3){
                get_Formal_Parameter(head->children[2]->children[1], subprogram_declaration->parameter);
            }
        }
        else if(head->children.size() == 3){
            subprogram_declaration->mold = "procedure";
            subprogram_declaration->ID = {head->children[1]->value, head->children[1]->line};
            if(head->children[2]->children.size() == 3){
                get_Formal_Parameter(head->children[2]->children[1], subprogram_declaration->parameter);
            }
        }
        subprogram_declaration->program_body = get_Program_Body(res->children[2]);
        V.push_back(subprogram_declaration);
    }
}
//parameter_lists: parameter_lists SEMICOLON parameter_list | parameter_list
//parameter_list: var_parameter | value_parameter
//var_parameter: VAR value_parameter
//value_parameter: identifier_list COLON standard_type
void get_Formal_Parameter(const parse* now, vector<Formal_Parameter*>& V)
{
    if(now->children.size() == 3){
        get_Formal_Parameter(now->children[0], V);
        Formal_Parameter* formal_parameter = new Formal_Parameter();
        parse* res = now->children[2];
        if(res->children[0]->token == "var_parameter"){
            formal_parameter->is_reference = true;
            res = res->children[0]->children[1];
        }
        else if(res->children[0]->token == "value_parameter"){
            res = res->children[0];
        }
        get_Id_List(res->children[0], formal_parameter->ID);
        formal_parameter->type = {res->children[2]->children[0]->value, res->children[2]->children[0]->line};
        V.push_back(formal_parameter);   
    }
    else if(now->children.size() == 1){
        Formal_Parameter* formal_parameter = new Formal_Parameter();
        parse* res = now->children[0];
        if(res->children[0]->token == "var_parameter"){
            formal_parameter->is_reference = true;
            res = res->children[0]->children[1];
        }
        else if(res->children[0]->token == "value_parameter"){
            res = res->children[0];
        }
        get_Id_List(res->children[0], formal_parameter->ID);
        formal_parameter->type = {res->children[2]->children[0]->value, res->children[2]->children[0]->line};
        V.push_back(formal_parameter);
    }
}
//compound_statement: BEGINN statement_list END
Compound_Statement* get_Compound_Statement(const parse* now)
{
    Compound_Statement* compound_statement = new Compound_Statement();
    compound_statement->type = "compound";
    get_Statement_List(now->children[1], compound_statement->statement_list);
    return compound_statement;
}
//statement_list: statement_list SEMICOLON statement | statement
void get_Statement_List(const parse* now, vector<Statement*> &V)
{
    if(now->children.size() == 3){
        get_Statement_List(now->children[0], V);
        Statement* statement = get_Statement(now->children[2]);
        if(statement != nullptr){
            V.push_back(statement);
        }
    }
    else if(now->children.size() == 1){
        Statement* statement = get_Statement(now->children[0]);
        if(statement != nullptr){
            V.push_back(statement);
        }
    }
}
/*statement: variable ASSIGNOP expression |
             call_procedure_statement |
             compound_statement | 
             IF expression THEN statement else_part | 
             CASE expression OF case_body END | 
             WHILE expression DO statement | 
             REPEAT statement_list UNTIL expression | 
             FOR ID ASSIGNOP expression updown expression DO statement | 
               
*/          
Statement* get_Statement(const parse* now)
{
    if(now->children.size() == 0){
        return nullptr;
    }
    string token = now->children[0]->token;
    Statement* statement = nullptr;
    if(token == "variable"){
        statement = (Statement*) get_Assign_Statement(now->children[0], now->children[2]);
    }
    else if(token == "call_procedure_statement"){
        statement = (Statement*) get_Procedure_Statement(now->children[0]);
    }
    else if(token == "compound_statement"){
        statement = (Statement*) get_Compound_Statement(now->children[0]);
    }
    else if(token == "IF"){
        statement = (Statement*) get_IF_Statement(now->children[1], now->children[3], now->children[4]);
    }
    else if(token == "CASE"){
        statement = (Statement*) get_CASE_Statement(now->children[1], now->children[3]);
    }
    else if(token == "WHILE"){
        statement = (Statement*) get_WHILE_Statement(now->children[1], now->children[3]);
    }
    else if(token == "REPEAT"){
        statement = (Statement*) get_REPEAT_Statement(now->children[1], now->children[3]);
    }
    else if(token == "FOR"){
        statement = (Statement*) get_FOR_Statement(now->children[1], now->children[3], now->children[4], now->children[5],  now->children[7]);
    }
    return statement;
}
//statement: variable ASSIGNOP expression
Assign_Statement* get_Assign_Statement(const parse* variable, const parse* expression)
{
    Assign_Statement* assign_statement = new Assign_Statement();
    assign_statement->type = "assign";
    assign_statement->variable = get_Variable(variable);
    assign_statement->expression = get_Expression(expression);
    return assign_statement;
}
//variable: ID id_varparts
//id_varparts: id_varparts id_varpart | 
//id_varpart: LBAR expression_list RBAR | DOT ID
Variable* get_Variable(const parse* now)
{
    Variable* variable = new Variable();
    variable->ID = {now->children[0]->value, now->children[0]->line};
    if(now->children[1]->children.size() == 0){
        variable->type = (variable->type | 0b100);
    }
    else{
        get_Id_Varparts(now->children[1], variable->type, variable->array_range, variable->record_ID, variable->order);
    }
    return variable;
}
//id_varparts: id_varparts id_varpart | 
//id_varpart: LBAR expression_list RBAR | DOT ID
void get_Id_Varparts(const parse* now, int& type, vector<vector<Expression*>>& V1, vector<string>& V2, vector<int>& V3)
{
    if(now->children.size() == 0){
        return;
    }
    else if(now->children.size() == 2){
        get_Id_Varparts(now->children[0], type, V1, V2, V3);
        parse* res = now->children[1];
        if(res->children.size() == 3){
            type = (type | 0b010);
            vector<Expression*> V;
            get_Expression_List(res->children[1], V);
            V1.push_back(V);
            V3.push_back(0);
        }
        else if(res->children.size() == 2){
            type = (type | 0b001);
            V2.push_back(res->children[1]->value);
            V3.push_back(1);
        }
    }
}
//statement:call_procedure_statement
//call_procedure_statement: ID | ID LPAR expression_list RPAR
Procedure_Statement* get_Procedure_Statement(const parse* now)
{
    Procedure_Statement* procedure_statement = new Procedure_Statement();
    procedure_statement->type = "procedure";
    if(now->children.size() == 4){
        procedure_statement->ID = {now->children[0]->value, now->children[0]->line};
        get_Expression_List(now->children[2], procedure_statement->actual_parameter);
    }
    else if(now->children.size() == 1){
        procedure_statement->ID = {now->children[0]->value, now->children[0]->line};
    }
    return procedure_statement;
}
//statement: IF expression THEN statement else_part
//else_part: ELSE statement | 
IF_Statement* get_IF_Statement(const parse* expression, const parse* then_statement, const parse* else_part)
{
    IF_Statement* if_statement = new IF_Statement();
    if_statement->type = "if";
    if_statement->expression = get_Expression(expression);
    if_statement->then_statement = get_Statement(then_statement);
    if(else_part->children.size() == 2){
        if_statement->else_statement = get_Statement(else_part->children[1]);
    }
    return if_statement;
}
//statement: CASE expression OF case_body END
//case_body: branch_list | 
CASE_Statement* get_CASE_Statement(const parse* expression, const parse* case_body)
{
    CASE_Statement* case_statement = new CASE_Statement();
    case_statement->type = "case";
    case_statement->expression = get_Expression(expression);
    if(case_body->children.size() == 1){
        get_Branch(case_body->children[0], case_statement->branch);
    }
    return case_statement;
}
//branch_list: branch_list SEMICOLON branch | branch
//branch: const_list COLON statement
void get_Branch(const parse* now, vector<Branch*>& V)
{
    if(now->children.size() == 3){
        get_Branch(now->children[0], V);
        parse* res = now->children[2];
        Branch* branch = new Branch();
        get_Const_List(res->children[0], branch->const_list);
        branch->statement = get_Statement(res->children[2]);
        V.push_back(branch);
    }
    else if(now->children.size() == 1){
        parse* res = now->children[0];
        Branch* branch = new Branch();
        get_Const_List(res->children[0], branch->const_list);
        branch->statement = get_Statement(res->children[2]);
        V.push_back(branch);
    }
}
//const_list: const_list COMMA const_variable | const_variable
void get_Const_List(const parse* now, vector<Const_Variable*>& V)
{
    if(now->children.size() == 3){
        get_Const_List(now->children[0], V);
        Const_Variable* const_variable = get_Const_Variable(now->children[2]);
        V.push_back(const_variable);
    }
    else if(now->children.size() == 1){
        Const_Variable* const_variable = get_Const_Variable(now->children[0]);
        V.push_back(const_variable);
    }
}
//statement: WHILE expression DO statement
WHILE_Statement* get_WHILE_Statement(const parse* expression, const parse* statement)
{
    WHILE_Statement* while_statement = new WHILE_Statement();
    while_statement->type = "while";
    while_statement->expression = get_Expression(expression);
    while_statement->statement = get_Statement(statement);
    return while_statement;
}
//statement: REPEAT statement_list UNTIL expression
REPEAT_Statement* get_REPEAT_Statement(const parse* statement_list, const parse* expression)
{
    REPEAT_Statement* repeat_statement = new REPEAT_Statement();
    repeat_statement->type = "repeat";
    get_Statement_List(statement_list, repeat_statement->statement);
    repeat_statement->expression = get_Expression(expression);
    return repeat_statement;
}
//statement: FOR ID ASSIGNOP expression updown expression DO statement
//updown: TO | DOWNTO
FOR_Statement* get_FOR_Statement(const parse* ID, const parse* expression1 , const parse* updown, const parse* expression2, const parse* statement)
{
    FOR_Statement* for_statement = new FOR_Statement();
    for_statement->type = "for";
    for_statement->ID = {ID->value, ID->line};
    for_statement->first_expression = get_Expression(expression1);
    for_statement->second_expression = get_Expression(expression2);
    for_statement->statement = get_Statement(statement);
    if(updown->children[0]->token == "TO"){
        for_statement->is_up = true;
    }
    return for_statement;
}
//expression_list: expression_list COMMA expression | expression
void get_Expression_List(const parse* now, vector<Expression*>& V)
{
    if(now->children.size() == 3){
        get_Expression_List(now->children[0], V);
        Expression* expression = get_Expression(now->children[2]);
        V.push_back(expression);
    }
    else if(now->children.size() == 1){
        Expression* expression = get_Expression(now->children[0]);
        V.push_back(expression);
    }
}
//expression: simple_expression RELOP simple_expression | simple_expression
//RELOP: EQUAL | NEQUAL | LESS | LE | GREATER | GE
Expression* get_Expression(const parse* now)
{
    if(now->children.size() == 3){
        Expression* expression = new Expression();
        expression->operationType = "relop";
        expression->operand_left = get_Simple_Expression(now->children[0]);
        expression->operand_right = get_Simple_Expression(now->children[2]);
        expression->relop_type = now->children[1]->children[0]->value;
        return expression;
    }
    else if(now->children.size() == 1){
        Expression* expression = new Expression();
        expression->operationType = "single";
        expression->operand_left = get_Simple_Expression(now->children[0]);
        return expression;
    }
    else{
        return nullptr;
    }
}
//simple_expression: term | ADD term | SUB term | simple_expression ADDOP term
//ADDOP: ADD | SUB | OR
Simple_Expression* get_Simple_Expression(const parse* now)
{
    if(now->children.size() == 3){
        Simple_Expression* simple_expression = new Simple_Expression();
        simple_expression->operationType = "ADDOP";
        simple_expression->operand_left = get_Simple_Expression(now->children[0]);
        simple_expression->operand_right = get_Term(now->children[2]);
        simple_expression->ADDOP_type = now->children[1]->children[0]->value;
        return simple_expression;
    }
    else if(now->children.size() == 2){
        Simple_Expression* simple_expression = new Simple_Expression();
        simple_expression->operationType = now->children[0]->value;
        simple_expression->operand_right = get_Term(now->children[1]);
        return simple_expression;
    }
    else if(now->children.size() == 1){
        Simple_Expression* simple_expression = new Simple_Expression();
        simple_expression->operationType = "single";
        simple_expression->operand_right = get_Term(now->children[0]);
        return simple_expression;
    }
    else{
        return nullptr;
    }
}
//term: term MULOP factor | factor
//MULOP: MUL | DIVISION | DIV | MOD | AND
Term* get_Term(const parse* now)
{
    if(now->children.size() == 3){
        Term* term = new Term();
        term->operationType = "MULOP";
        term->MULOP_type = now->children[1]->children[0]->value;
        term->operand_left = get_Term(now->children[0]);
        term->operand_right = get_Factor(now->children[2]);
        return term;
    }
    else if(now->children.size() == 1){
        Term* term = new Term();
        term->operationType = "single";
        term->operand_right = get_Factor(now->children[0]);
        return term;
    }
    else{
        return nullptr;
    }
}
//factor: unsign_const_variable
//        | variable
//        | ID LPAR expression_list RPAR
//        | LPAR expression RPAR
//        | NOT factor
Factor* get_Factor(const parse* now)
{
    string token = now->children[0]->token;
    if(token == "unsign_const_variable"){
        Factor* factor = new Factor();
        factor->type = 1;
        factor->unsigned_const_variable = get_Unsigned_Const_Variable(now->children[0]);
        return factor;
    }
    else if(token == "variable"){
        Factor* factor = new Factor();
        factor->type = 2;
        factor->variable = get_Variable(now->children[0]);
        return factor;
    }
    else if(token == "ID"){
        Factor* factor = new Factor();
        factor->type = 3;
        factor->ID = {now->children[0]->value, now->children[0]->line};
        get_Expression_List(now->children[2], factor->func_expression);
        return factor;
    }
    else if(token == "LPAR"){
        Factor* factor = new Factor();
        factor->type = 4;
        factor->expression = get_Expression(now->children[1]);
        return factor;
    }
    else if(token == "NOT"){
        Factor* factor = new Factor();
        factor->type = 5;
        factor->is_not = true;
        factor->factor = get_Factor(now->children[1]);
        return factor;
    }
    else{
        return nullptr;
    }
}
//unsign_const_variable: NUM | SSCH | MMCH
Unsigned_Const_Variable* get_Unsigned_Const_Variable(const parse* now)
{
    Unsigned_Const_Variable* unsigned_const_variable = new Unsigned_Const_Variable();
    if(now->children[0]->token == "INT"){
        unsigned_const_variable->var_value = {now->children[0]->value, now->children[0]->line};
        unsigned_const_variable->int_value = atoi(now->children[0]->value.c_str());
        unsigned_const_variable->mold = "int";
    }
    else if(now->children[0]->token == "FLOAT"){
        unsigned_const_variable->var_value = {now->children[0]->value, now->children[0]->line};
        unsigned_const_variable->float_value = atof(now->children[0]->value.c_str());
        unsigned_const_variable->mold = "float";            
    }
    else if(now->children[0]->token == "SSCH"){
        unsigned_const_variable->var_value = {now->children[0]->value, now->children[0]->line};
        unsigned_const_variable->c = now->children[0]->value[0];
        unsigned_const_variable->mold = "char";            
    }
    else if(now->children[0]->token == "MMCH"){
        unsigned_const_variable->var_value = {now->children[0]->value, now->children[0]->line};
        unsigned_const_variable->str = now->children[0]->value;
        unsigned_const_variable->mold = "string";            
    }
    return unsigned_const_variable;
}

Program* parse_to_AST(const parse* root)
{
    return get_Program(root);
}